home *** CD-ROM | disk | FTP | other *** search
- // Copyright (c) 1994, University of Kansas, All Rights Reserved
- //
- // Class: TDosLynx
- // Include File: tdoslynx.h
- // Purpose: Application for WWW client
- // Remarks/Portability/Dependencies/Restrictions:
- // Revision History:
- // 04-04-94 created
- #define Uses_TRect
- #define Uses_TDialog
- #define Uses_TStaticText
- #define Uses_TInputLine
- #define Uses_TLabel
- #define Uses_TMemo
- #define Uses_TButton
- #define Uses_TProgram
- #define Uses_TDeskTop
- #include"tdoslynx.h"
- #include"globals.h"
- #include"trace.h"
- extern "C" {
- #include"msdostcp.h"
- };
- #include<string.h>
-
- // The port number of the SMTP service on a networked macine.
- const int i_SMTPPort = 25;
-
- // CR/LF sequence used over the net.
- char *cp_crlf = "\r\n";
-
- void TDosLynx::mailDeveloper() {
- // Purpose: Allow user to send a mail message to whoever is
- // ill fated enough to have to maintain this code!
- // Arguments: void
- // Return Value: void
- // Remarks/Portability/Dependencies/Restrictions:
- // Based on RFC 821, SMTP
- // Revision History:
- // 04-04-94 created
-
- // General use rectangle.
- auto TRect TR;
-
- // Create a good sized dialog.
- TR = TRect(0, 0, 74, 22);
- auto TDialog *TDp_mail = new TDialog(TR, "Mail Developer");
-
- // Set some dialog options.
- TDp_mail->options |= ofCentered;
-
- // General use buffer.
- auto char *cp_buffer = new char[4096];
-
- // Create some static text to show what is happening.
- TR = TRect(2, 1, 72, 2);
- strcpy(cp_buffer, "To: doslynx@falcon.cc.ukans.edu");
- auto TStaticText *TSTp_rcpt = new TStaticText(TR, cp_buffer);
- TDp_mail->insert(TSTp_rcpt);
-
- TR = TRect(2, 2, 72, 3);
- strcpy(cp_buffer, "From: doslynxuser@");
- extern unsigned long my_ip_addr;
- inet_ntoa(cp_buffer + strlen(cp_buffer), my_ip_addr);
- auto TStaticText *TSTp_from = new TStaticText(TR, cp_buffer);
- TDp_mail->insert(TSTp_from);
-
- // Create the reply to input line.
- TR = TRect(12, 3, 72, 4);
- auto TInputLine *TILp_reply = new TInputLine(TR, usi_TILURLSize - 1);
- if(::cp_ReplyTo != NULL) {
- TILp_reply->setData((void *)::cp_ReplyTo);
- }
- TDp_mail->insert(TILp_reply);
-
- TR = TRect(1, 3, 11, 4);
- auto TLabel *TLp_reply = new TLabel(TR, "~R~eply-To:", TILp_reply);
- TDp_mail->insert(TLp_reply);
-
- // Create the subject to input line.
- TR = TRect(12, 4, 72, 5);
- auto TInputLine *TILp_subject = new TInputLine(TR, usi_TILURLSize - 1);
- TILp_subject->setData((void *)"DosLynx v0.71a");
- TDp_mail->insert(TILp_subject);
-
- TR = TRect(1, 4, 11, 5);
- auto TLabel *TLp_subject = new TLabel(TR, "S~u~bject:", TILp_subject);
- TDp_mail->insert(TLp_subject);
-
- // Create the user editable area for the message.
- TR = TRect(2, 7, 72, 18);
- auto TMemo *TMp_message = new TMemo(TR, NULL, NULL, NULL, 4096 -
- sizeof(unsigned short int));
- TDp_mail->insert(TMp_message);
-
- TR = TRect(1, 6, 72, 7);
- auto TLabel *TLp_message = new TLabel(TR, "~M~essage:", TMp_message);
- TDp_mail->insert(TLp_message);
-
- // Create the Send and Cancel buttons.
- TR = TRect(15, 19, 27, 21);
- auto TButton *TBp_send = new TButton(TR, "~S~end", cmOK, bfDefault);
- TDp_mail->insert(TBp_send);
-
- TR = TRect(47, 19, 59, 21);
- auto TButton *TBp_cancel = new TButton(TR, "~C~ancel", cmCancel,
- bfNormal);
- TDp_mail->insert(TBp_cancel);
-
- // Done with the dialog.
- // Stay in reply field.
- TDp_mail->selectNext(False);
-
- // Draw it.
- TDp_mail->drawView();
-
- // Execute. Code does nothing if user cancels.
- if(TProgram::deskTop->execView(TDp_mail) != cmCancel) {
- // Time to send the mail.
-
- // Obtain a socket.
- #ifndef RELEASE
- trace("getting socket.");
- #endif // RELEASE
- auto int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if(sockfd == -1) {
- destroy(TDp_mail);
- doslynxmessage("Unable to obtain a socket. No mail "
- "sent.");
- delete(cp_buffer);
- return;
- }
-
- // Resolve address.
- #ifndef RELEASE
- trace("resolving address.");
- #endif // RELEASE
- auto struct sockaddr_in sin;
- sin.sin_family = AF_INET;
- sin.sin_port = ntohs(i_SMTPPort);
- sin.sin_addr.s_addr = resolve("falcon.cc.ukans.edu");
- if(sin.sin_addr.s_addr == 0UL) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("DNSLookup failed for SMTP host. "
- "No mail sent.");
- delete(cp_buffer);
- return;
- }
-
- // Connect to SMTP host
- #ifndef RELEASE
- trace("connecting to SMTP host.");
- #endif // RELEASE
- if(connect(sockfd, (sockaddr *)(&sin),
- sizeof(struct sockaddr_in)) < 0) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("Unable to connect to SMTP host. "
- "No mail sent.");
- delete(cp_buffer);
- return;
- }
-
- // Since we are connected, start doing the SMTP thing.
-
- // Check for 220 response.
- cp_buffer[0] = '\0';
- s_read(sockfd, cp_buffer, 4095);
- if(strstr(cp_buffer, "220") == NULL) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("SMTP host not responding. "
- "No mail sent.");
- delete(cp_buffer);
- return;
- }
-
- // Send HELO
- sprintf(cp_buffer, "HELO %s.%s%s", gethostname(NULL, 0) ==
- NULL ? "doslynx" : gethostname(NULL, 0),
- getdomainname(NULL, 0) == NULL ? "i.dont.know" :
- getdomainname(NULL, 0), cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- // Check for 250 response.
- cp_buffer[0] = '\0';
- s_read(sockfd, cp_buffer, 4095);
- if(strstr(cp_buffer, "250") == NULL) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("SMTP host not responding. "
- "No mail sent.");
- delete(cp_buffer);
- return;
- }
-
- // Send MAIL FROM
- sprintf(cp_buffer, "MAIL FROM:<doslynxuser@");
- inet_ntoa(cp_buffer + strlen(cp_buffer), my_ip_addr);
- strcat(cp_buffer, ">");
- strcat(cp_buffer, cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- // Check for 250 response.
- cp_buffer[0] = '\0';
- s_read(sockfd, cp_buffer, 4095);
- if(strstr(cp_buffer, "250") == NULL) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("SMTP host refusing to accept. "
- "No mail sent.");
- delete(cp_buffer);
- return;
- }
-
- // Send RCPT TO
- sprintf(cp_buffer, "RCPT TO:<doslynx@falcon.cc.ukans.edu>%s",
- cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- // Check for 250 or 251 response.
- cp_buffer[0] = '\0';
- s_read(sockfd, cp_buffer, 4095);
- if(strstr(cp_buffer, "250") == NULL && strstr(cp_buffer,
- "251") == NULL) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("SMTP host refusing to accept. "
- "No mail sent.");
- delete(cp_buffer);
- return;
- }
-
- // Send DATA
- sprintf(cp_buffer, "DATA%s", cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- // Check for 354 response.
- cp_buffer[0] = '\0';
- s_read(sockfd, cp_buffer, 4095);
- if(strstr(cp_buffer, "354") == NULL) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("SMTP host refusing to accept. "
- "No mail sent.");
- delete(cp_buffer);
- return;
- }
-
- // Send some normal mail header stuff.
- #ifndef RELEASE
- trace("writing message header.");
- #endif // RELEASE
- auto time_t tt_time = time(NULL);
- sprintf(cp_buffer, "Date: %s", ctime(&tt_time));
- strcpy(cp_buffer + strlen(cp_buffer) - 1, cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- sprintf(cp_buffer, "To: DosLynx Developer <doslynx@"
- "falcon.cc.ukans.edu>%s", cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- strcpy(cp_buffer, "From: \"");
- inet_ntoa(cp_buffer + strlen(cp_buffer), my_ip_addr);
- strcat(cp_buffer, "\" <doslynxuser@");
- if(gethostname(NULL, 0) != NULL) {
- strcat(cp_buffer, gethostname(NULL, 0));
- if(getdomainname(NULL, 0) != NULL) {
- strcat(cp_buffer, ".");
- strcat(cp_buffer, getdomainname(NULL, 0));
- }
- }
- else {
- inet_ntoa(cp_buffer + strlen(cp_buffer), my_ip_addr);
- }
- strcat(cp_buffer, ">");
- strcat(cp_buffer, cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- TILp_reply->getData((void *)cp_buffer);
- if(cp_buffer[0] != '\0') {
- s_write(sockfd, "Reply-To: ", 11);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
- s_write(sockfd, cp_crlf, strlen(cp_crlf));
- }
-
- TILp_subject->getData((void *)cp_buffer);
- if(cp_buffer[0] != '\0') {
- s_write(sockfd, "Subject: ", 11);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
- s_write(sockfd, cp_crlf, strlen(cp_crlf));
- }
- else {
- sprintf(cp_buffer, "Subject: (none)%s", cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
- }
-
- // Start sending the body of the message.
- // Use the scheme stated in rfc 821.
- // We will skip the first sizeof(unsigned short int)
- // bytes because they are meaningless.
- #ifndef RELEASE
- trace("writing message body.");
- #endif // RELEASE
- TMp_message->getData((void *)cp_buffer);
- auto char *cp_convert = cp_buffer + sizeof(unsigned short int);
-
- // Convert buffer into the rfc821 compliant message.
- for(;cp_convert != '\0'; cp_convert++) {
- // Do nothing unless a newline or a '.'
-
- // Here, we will have to add stuff to the
- // buffer if it is a newline or a '.' at the
- // start of a line.
- if(*cp_convert == '.') {
- // To be at the start of a line, the
- // '.' is either the very first line
- // or is preceded by a newline.
- if(cp_convert == cp_buffer + sizeof(unsigned
- short int) || *(cp_convert - 1) ==
- '\n') {
- // First, move so that there is
- // enough space in the buffer.
- // Start from the end.
- for(auto char *cp_double = cp_convert
- + strlen(cp_convert);
- cp_double >= cp_convert;
- cp_double--) {
- *(cp_double + 1) = *cp_double;
- }
-
- // Increment cp_convert by one
- // since added a character.
- cp_convert++;
- }
- }
- else if(*cp_convert == '\n') {
- // Turn this into a cp_crlf.
- // First, move so that there is
- // enough space in the buffer.
- // Start from the end.
- for(auto char *cp_double = cp_convert
- + strlen(cp_convert);
- cp_double >= cp_convert;
- cp_double--) {
- *(cp_double + 1) = *cp_double;
- }
-
- // Increment cp_convert by one
- // since added a character.
- // Convert the \n now pointed at to a
- // \r
- *cp_convert = '\r';
- cp_convert++;
- }
- }
-
- // Write the message body.
- s_write(sockfd, cp_buffer + sizeof(unsigned short int),
- strlen(cp_buffer + sizeof(unsigned short int)));
-
- // Done. Write the ending of the message and close the
- // socket.
- sprintf(cp_buffer, "%s%c%s", cp_crlf, '.', cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- // Check for 250 response
- cp_buffer[0] = '\0';
- s_read(sockfd, cp_buffer, 4095);
- if(strstr(cp_buffer, "250") == NULL) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("SMTP host did not accept message.");
- delete(cp_buffer);
- return;
- }
-
- // Send QUIT
- sprintf(cp_buffer, "QUIT%s", cp_crlf);
- s_write(sockfd, cp_buffer, strlen(cp_buffer));
-
- // Check for 221 response.
- cp_buffer[0] = '\0';
- s_read(sockfd, cp_buffer, 4095);
- if(strstr(cp_buffer, "221") == NULL) {
- destroy(TDp_mail);
- s_close(sockfd);
- doslynxmessage("SMTP host wouldn't end session.");
- delete(cp_buffer);
- return;
- }
-
- // Close the socket. We're done.
- s_close(sockfd);
- doslynxmessage("Mail message was sent.");
- }
-
- // Destroy the dialog.
- destroy(TDp_mail);
-
- // Get rid of our buffer.
- delete(cp_buffer);
- }